
#if	!defined( __20081117_DEF_WIN_LOCK_H__ )
#define	__20081117_DEF_WIN_LOCK_H__

#include	<assert.h>
#include	<windows.h>

// undefine macro defined in windows.h
#ifdef	max
#undef	max
#endif

#ifdef	min
#undef	min
#endif

namespace PCE_Lib {
namespace CEnv_Def {
namespace PCE_Lib_CurrentCEnvironment {
namespace Tools {

class Lock
{
public:
	/**
	 *	return true: get lock
	 *	return false: error
	 */
	bool GetLock( void ) throw()
	{
		assert( NotNull( m_Mutex ) );
		switch( WaitForSingleObject( m_Mutex, INFINITE ) )
		{
		case WAIT_OBJECT_0:
			return true;
		case WAIT_ABANDONED: case WAIT_TIMEOUT: default:
			return false;
		}
	}
	/**
	 *	return true: ( status = true: get lock; = false: do not get lock )
	 *	return false: error
	 */
	bool TryLock( bool & status ) throw()
	{
		assert( NotNull( m_Mutex ) );
		switch( WaitForSingleObject( m_Mutex, 0 ) )
		{
		case WAIT_OBJECT_0:	status = true; return true;
		case WAIT_TIMEOUT:	status = false; return true;
		case WAIT_ABANDONED: default:	return false;
		}
	}
	/**
	 *	return true: release lock ok
	 *	return false: error, cannot release lock
	 */
	bool ReleaseLock( void ) throw()
	{
		assert( NotNull( m_Mutex ) );
		return 0 != ReleaseMutex( m_Mutex );
	}
public:
	/**
	 *	1. Free mutex; 2. Create a new
	 */
	bool Alloc( bool ownership= false ) throw()
	{
		if( ! Free() ) {
			return false;
		}
		assert( IsNull( m_Mutex ) );

		m_Mutex = CreateMutex(
			Null< LPSECURITY_ATTRIBUTES >(),
			ownership ? TRUE : FALSE,
			Null< LPCTSTR >() );
		return NotNull( m_Mutex );
	}
	/**
	 *	If retrun true, succeed; if return false, do not free
	 */
	bool Free( void ) throw()
	{
		if( IsNull( m_Mutex ) ) {
			return true;
		}
		if( 0 == CloseHandle( m_Mutex ) ) {
			return false;
		}
		SetNull( m_Mutex );
		return true;
	}
public:
	Lock( void ) throw() : m_Mutex() {}
	~Lock( void ) throw()
	{
		if( IsNull( m_Mutex ) ) {
			return;
		}
		CloseHandle( m_Mutex );
	}
protected:
	HANDLE		m_Mutex;
};

}	// Tools
}	// PCE_Lib_CurrentCEnvironment
}	// CEnv_Def
}	// PCE_Lib

#endif	// __20081117_DEF_WIN_LOCK_H__
